package com.codeoss.framework.view.renderer;

import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import com.codeoss.framework.context.YunContext;
import com.codeoss.framework.expression.Expression;
import com.codeoss.framework.expression.IScriptService;
import com.codeoss.framework.expression.IScriptServiceStore;
import com.codeoss.framework.view.component.Component;
import com.codeoss.framework.view.component.Container;
import com.codeoss.framework.view.renderer.store.IComponentRendererStore;

@Service
public  class CommonComponentRenderer implements IComponentRenderer,ApplicationContextAware {
	private ApplicationContext applicationContext;
	@Autowired
	private IScriptServiceStore ScriptServiceStore;
	@Override
	public ViewSerializeMap renderView(YunContext yunContext, Component component) {
		// TODO Auto-generated method stub
		ViewSerializeMap serializeMap = new ViewSerializeMap();
		startRenderView(yunContext, component, serializeMap);
		if (isRenderChildrenView(yunContext,component) && component instanceof Container) {
			renderChildrenView(yunContext, (Container) component, serializeMap);
		}
		endRenderView(yunContext, component, serializeMap);
		return serializeMap;
	}

	protected void startRenderView(YunContext yunContext, Component component, ViewSerializeMap viewSerializeMap) {
		viewSerializeMap.put(ComponentAttrConstants.ID,component.getId());
		viewSerializeMap.put(ComponentAttrConstants.TYPE, component.getType());
		Expression cssStyleExpression=component.getCssStyleExpression();
		if(cssStyleExpression!=null) {
			IScriptService scriptService=ScriptServiceStore.getScriptService(cssStyleExpression);
			String cssStyle=(String)scriptService.eval(cssStyleExpression.getScript(), yunContext.getVarValueMap());
			viewSerializeMap.put("cssStyle", cssStyle);
		}
		
		Expression cssClassExpression=component.getCssClassExpression();
		if(cssClassExpression!=null) {
			IScriptService scriptService=ScriptServiceStore.getScriptService(cssStyleExpression);
			String cssClass=(String)scriptService.eval(cssClassExpression.getScript(), yunContext.getVarValueMap());
			viewSerializeMap.put("cssClass", cssClass);
		}
	}
	
	protected void renderChildrenView(YunContext yunContext, Container c, ViewSerializeMap viewSerializeMap) {
		List<Component> children = c.getChildren();
		for (int i = 0; i < children.size(); i++) {
			Component childComponent = children.get(i);
			IComponentRendererStore componentRendererStore = applicationContext.getBean(IComponentRendererStore.class);
			IComponentRenderer componentRenderer = componentRendererStore.getComponentRenderer(yunContext,
					childComponent);
			ViewSerializeMap childSerializeObject = (ViewSerializeMap) componentRenderer.renderView(yunContext,
					childComponent);
			viewSerializeMap.addChild(childSerializeObject);
		}
	}
	
	protected void endRenderView(YunContext yunContext, Component component, ViewSerializeMap viewSerializeMap) {

	}
	
	
	protected boolean isRenderChildrenView(YunContext yunContext,Component component) {
		return true;
	}
	
	@Override
	public PropSerializeMap renderProp(YunContext yunContext, Component component, ViewPropMap viewPropMap) {
		// TODO Auto-generated method stub
		PropSerializeMap propSerializeMap = startRenderProp(yunContext, component, viewPropMap);
		if (isRenderChildrenProp(yunContext) && component instanceof Container) {
			renderChildrenProp(yunContext, (Container) component, viewPropMap,propSerializeMap);
		}
		endRenderProp(yunContext, component, viewPropMap, propSerializeMap);
		return propSerializeMap;
	}

	protected PropSerializeMap startRenderProp(YunContext yunContext,
			Component component, ViewPropMap viewPropMap) {
		PropSerializeMap propSerializeMap = createPropSerializeMap(yunContext, component, viewPropMap);
		return propSerializeMap;
	}

	protected void renderChildrenProp(YunContext yunContext,
			Container c, ViewPropMap viewPropMap, PropSerializeMap propSerializeMap) {
		List<Component> children = c.getChildren();
		for (int i = 0; i < children.size(); i++) {
			IComponentRendererStore componentRendererStore = applicationContext.getBean(IComponentRendererStore.class);
			Component childComponent = children.get(i);
			IComponentRenderer componentRenderer = componentRendererStore.getComponentRenderer(yunContext,
					childComponent);
			PropSerializeMap childPropSerializeMap = (PropSerializeMap) componentRenderer.renderProp(yunContext, childComponent, viewPropMap);
			if (childPropSerializeMap != null) {
				viewPropMap.put(childComponent.getId(), childPropSerializeMap);
			}
		}
	}

	protected boolean isRenderChildrenProp(YunContext yunContext) {
		return true;
	}

	protected void endRenderProp(YunContext yunContext,
			Component component, ViewPropMap viewPropMap, PropSerializeMap propSerializeMap) {

	}
	
	protected PropSerializeMap createPropSerializeMap(YunContext yunContext, Component component,
			ViewPropMap viewPropMap) {
		PropSerializeMap dataSerializeMap = new PropSerializeMap();
		viewPropMap.put(component.getId(), dataSerializeMap);
		return dataSerializeMap;
	}
	
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		// TODO Auto-generated method stub
		this.applicationContext=applicationContext;
	}

}
